"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

"""
"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 开启按需回放参数进行备2节点stop操作
Create At   : 2024-04-07
Owner       : zhenjinyang
Description :
    1、查看集群状态; expect:集群状态正常
    2、switchover -a恢复集群状态为初始状态
    3、加载ondemand参数; expect:执行成功
    4、重启; expect:执行成
    5、检验参数; expect:执行成功
    6、第2个节点：备节点2进行stop; expect:执行成功
    7、再次查看切换后集群状态 expect:集群状态正常,备1切换为主节点，原主节点降为备节点
    8、原主节点新备节点进行switchover
    9、ondemand参数回复初始状态; expect:执行成功
    10、集群停止; expect:执行成功
    11、原节点进行节点启动; expect:执行成功
    12、参数为初始状态; expect:成功
    13、恢复环境为初始集群状态; expect:成功
Expect      :
    1、查看集群状态; expect:集群状态正常
    2、1节点为主节点，2节点为备节点，3节点为备节点
    3、加载ondemand参数
    4、重启:执行成
    5、检验参数设置成功
    6、备1节点状态为down
    7、再次查看切换后集群状态 expect:集群状态正常,备1切换为主节点，原主节点降为备节点
    8、原主节点新备节点进行switchover
    9、ondemand参数回复初始状态
    10、集群停止
    11、原节点进行节点启动
    12、参数为初始状态
    13、恢复环境为初始集群状态：1节点为主节点，2节点为备节点，3节点为备节点
History     :
    1、2024-04-07 创建
"""

import os
import unittest
import time

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')
Standby1_SH = CommonSH('Standby1DbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()

        self.s1_comsh = CommonSH('Standby1DbUser')
        self.s2_comsh = CommonSH('Standby2DbUser')
        self.common = Common('Standby1DbUser')
        self.recovery_parse_workers = 'recovery_parse_workers'
        self.recovery_redo_workers = 'recovery_redo_workers'
        self.hot_standby = 'hot_standby'
        self.ss_enable_ondemand_recovery = 'ss_enable_ondemand_recovery'
        self.ss_ondemand_recovery_mem_size = 'ss_ondemand_recovery_mem_size'

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        if "cluster_state   : Normal" in status:
            self.log.info(status + "集群状态正常")
        else:
            stopdn = Primary_SH.exec_cm_ctl('stop')
            self.log.info(stopdn)
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            startdn = Primary_SH.exec_cm_ctl('start')
            self.log.info(startdn)
            self.assertIn(self.constant.cm_start_success_msg, startdn,
                    '拉起集群失败')
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            self.log.info(status)

        self.recovery_parse_workers_default = self.common.show_param(self.recovery_parse_workers)
        self.recovery_redo_workers_default = self.common.show_param(self.recovery_redo_workers)
        self.hot_standby_default = self.common.show_param(self.hot_standby)
        self.ss_enable_ondemand_recovery_default = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.ss_ondemand_recovery_mem_size_default = self.common.show_param(self.ss_ondemand_recovery_mem_size)

    def test_shared_storage(self):
        text = '-----step1:查看集群状态; expect:集群状态正常-----'
        self.log.info(text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step2:加载ondemand参数; expect:执行成功-----'
        self.log.info(text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_parse_workers}=2')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_redo_workers}=2')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.hot_standby}=off')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_enable_ondemand_recovery}=on')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_ondemand_recovery_mem_size}=5GB')
        self.assertTrue(result, '执行失败' + text)

        text = '-----step3:集群重启; expect:执行成功-----'
        self.log.info(text)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        text = '-----step4:检验参数; expect:执行成功-----'
        self.log.info(text)
        result_param = self.common.show_param(self.recovery_parse_workers)
        self.assertEquals(result_param, '2', '执行失败' + text)
        result_param = self.common.show_param(self.recovery_redo_workers)
        self.assertEquals(result_param, '2', '执行失败' + text)
        result_param = self.common.show_param(self.hot_standby)
        self.assertEquals(result_param, 'off', '执行失败' + text)
        result_param = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.assertEquals(result_param, 'on', '执行失败' + text)
        result_param = self.common.show_param(self.ss_ondemand_recovery_mem_size)
        self.assertEquals(result_param, '5GB', '执行失败' + text)

        text = '-----step5:备节点1 stop; expect:成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_cm_ctl(mode='stop',
                                           param='-n 2',
                                           path=f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(stopdn)
        self.assertIn("stop instance successfully", stopdn,
                '停止dn节点失败')

        text = '-----step6:查看集群状态; expect:集群状态Degraded-----'
        self.log.info(text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Degraded', status, '执行失败' + text)

        text = '-----step7:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')

        text = '-----step8:查看集群状态; expect:状态正常-----'
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn('     P Primary Normal ', res1, '执行失败' + text)

        text = '-----step9:ondemand参数回复初始状态; expect:执行成功-----'
        self.log.info(text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_parse_workers}={self.recovery_parse_workers_default}')
        self.assertTrue(result, '执行失败' + text)
        self.log.info(text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_redo_workers}={self.recovery_redo_workers_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.hot_standby}={self.hot_standby_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_enable_ondemand_recovery}={self.ss_enable_ondemand_recovery_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_ondemand_recovery_mem_size}={self.ss_ondemand_recovery_mem_size_default}')
        self.assertTrue(result, '执行失败' + text)

        text = '-----step10:集群停止; expect:执行成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn,
                '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn("Maybe cm_server is not running, or timeout expired. Please try again.", res1, '执行失败' + text)

        text = '-----step11:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step12:参数为初始状态; expect:成功-----'
        result_param = self.common.show_param(self.recovery_parse_workers)
        self.assertEquals(result_param, self.recovery_parse_workers_default, '执行失败' + text)
        result_param = self.common.show_param(self.recovery_redo_workers)
        self.assertEquals(result_param, self.recovery_redo_workers_default, '执行失败' + text)
        result_param = self.common.show_param(self.hot_standby)
        self.assertEquals(result_param, self.hot_standby_default, '执行失败' + text)
        result_param = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.assertEquals(result_param, self.ss_enable_ondemand_recovery_default, '执行失败' + text)
        result_param = self.common.show_param(self.ss_ondemand_recovery_mem_size)
        self.assertEquals(result_param, self.ss_ondemand_recovery_mem_size_default, '执行失败' + text)

    def tearDown(self):
        text = '-----step13:集群重启; expect:执行成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)

        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn,
                '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)

        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step14:恢复环境为初始集群状态; expect:成功-----'
        self.log.info(text)
        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                    status.splitlines()[-1].split('|')[2].split('6003')[-1],
                    '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')